//BFF 中间层
import express from 'express'
import { config } from 'dotenv'
config({
    path: ['.env.local', '.env']
})
const openaiApiKey = process.env.VITE_DEEPSEEK_API_KEY
const app = express()
const port = 3000
const endpoint = 'https://api.deepseek.com/chat/completions'
app.get('/stream', async (req, res) => {
    res.setHeader('Content-Type', 'text/event-stream')//设置响应头为事件流,给前端用的
    res.setHeader('Cache-Control', 'no-cache')//设置响应头为不缓存
    res.setHeader('Connection', 'keep-alive')//设置响应头为保持连接，就算保持连接，前端不发请求后端还是不会响应
    res.flushHeaders()//发送初始响应头
    try {
        const response = await fetch(endpoint, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${openaiApiKey}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                model: 'deepseek-chat',
                messages: [{ role: 'user', content: req.query.question }],
                stream: true
            })
        })
        const reader = response.body.getReader()  // 获取响应体的读取器（用于读取二进制流）
        const decoder = new TextDecoder()  // 创建解码器（将二进制数据转为字符串）
        let isDecodingComplete = false  // 标记是否解码完成
        let buffer = ''  // 缓冲区：存储不完整的分片数据（因流式传输可能分片到达）
        // 循环读取流数据，直到解码完成
        while (!isDecodingComplete) {
            // 读取二进制数据块：value是二进制数据，chunkDone标记当前块是否为最后一块
            const { value, done: chunkDone } = await reader.read()
            isDecodingComplete = chunkDone  // 更新解码完成标记（如果当前块为最后一块，则标记为true）
            // 将缓冲区残留数据与新解码的数据拼接（处理分片不完整的情况）
            const chunkValue = buffer + decoder.decode(value)
            buffer = ''  // 清空缓冲区，准备处理新数据
            // 按换行符分割数据，过滤出以"data:"开头的有效行（Deepseek流式响应格式）
            const lines = chunkValue.split('\n').filter(line => line.startsWith('data:'))
            // 提取非"data:"开头的内容（可能是不完整的分片），存入缓冲区
            const remaining = chunkValue.split('\n').filter(line => !line.startsWith('data:')).join('\n')
            if (remaining) {
                buffer = remaining  // 缓存不完整数据，等待下一次拼接
            }
            // 遍历每一行有效数据
            for (const line of lines) {
                const incoming = line.slice(6)  // 移除行首的"data:"（共6个字符）
                // 若遇到"[DONE]"，表示流式传输结束
                if (incoming === '[DONE]') {
                    isDecodingComplete = true  // 标记解码完成
                    break  // 退出循环
                }
                const data = JSON.parse(incoming)  // 解析JSON数据（Deepseek流式响应格式）
                const delta = data.choices[0].delta.content  // 提取当前响应的增量内容
                if (delta) {
                    res.write(`data:${ delta }\n\n`)  // 发送增量数据给前端（格式：data:{"delta":"..."}）
                }
            }
        }
        res.write('event:end\n')//发送结束事件
        res.write(`data:[DONE]\n\n`)  // 发送结束标记给前端,通知前端客户端数据流结束（格式：data:[DONE]）
        res.end()//结束响应
    } catch (error) {
        res.write('event:error\n')//发送错误事件
        res.write(`data:${error.message}\n\n`)//发送错误信息
        res.end()//结束响应
    }
})
app.listen(port, () => {
    console.log(`Server is running on port ${port}`)
})